﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Globalization;

namespace iLangl.Model
{
	public class ProjectResponseContext : BaseResponseContext
	{
		protected IProject _project = null;

		
		public override void SetContext(object context)
		{
			base.SetContext(context);

			if (document == null)
				return;

			XmlNodeList projects = document.SelectNodes("//Project");

			if ((projects == null) || (projects.Count == 0))
			{
				return;
			}

			XmlNode nodeProject = projects[0];

			_project = Facade.Instance.ModelFactory.CreateProject();
			ParseExtendedInfo(nodeProject, _project);

			
			if (nodeProject.Attributes["projId"] != null)
				_project.Id = nodeProject.Attributes["projId"].Value;
			if (nodeProject.Attributes["projName"] != null)
				_project.Name = nodeProject.Attributes["projName"].Value;
			if (nodeProject.Attributes["projDescriptor"] != null)
				_project.Description = nodeProject.Attributes["projDescriptor"].Value;

			if (nodeProject.Attributes["projDeadline"] != null)
			{
				string datetime = nodeProject.Attributes["projDeadline"].Value;
				try
				{
					_project.Deadline = DateTime.ParseExact(datetime, DefaultSettingsManager.DateTimeFormat, null);
				}
				catch (System.Exception ex)
				{
					throw ex;
					//TODO: save to log and send the warn
				}
			}

			if (nodeProject.Attributes["projStatus"] != null)
				_project.Status = nodeProject.Attributes["projStatus"].Value;

			//Extract Project Languages
			XmlNodeList nodelanguages = nodeProject.SelectNodes("//ProjectLanguages/Language");

			if (nodelanguages != null)
			{
				List<Language> languages = new List<Language>();

				foreach (XmlNode nodelanguage in nodelanguages)
				{
					Language lang = new Language();
					if (nodelanguage.Attributes["langId"] != null)
						lang.LanguageId = nodelanguage.Attributes["langId"].Value;

					if (nodelanguage.Attributes["langName"] != null)
						lang.LanguageName = nodelanguage.Attributes["langName"].Value;

					languages.Add(lang);
				}

				_project.SetProjectLanguages(languages);
			}


			//Extract Errors
			IList<IError> errors = null;

			ErrorsResponseContext errorResponseContext = new ErrorsResponseContext();
			errorResponseContext.SetContext(nodeProject);
			errors = (IList<IError>)errorResponseContext.GetContext();
			//TODO: Handle clients error on server side

			//Extract Contacts
			ContactResponseContext contactcontext = new ContactResponseContext();
			XmlNode contact = nodeProject.SelectSingleNode("//Owner/Contact");
			if (contact != null)
			{
				contactcontext.SetContext(contact);
				_project.Owner = (Contact)contactcontext.GetContext();
			}


			contact = nodeProject.SelectSingleNode("//TechnicalContact/Contact");
			if (contact != null)
			{
				contactcontext.SetContext(contact);
				_project.TechnicalContact = (Contact)contactcontext.GetContext();
			}


			//Extract Terminology
			XmlNodeList terminologies = nodeProject.SelectNodes("//Terminology");
			if ((terminologies == null) || (terminologies.Count == 0) || (terminologies.Count != 1))
			{
				//Send warning
			}

			XmlNode nodeterminology = terminologies[0];

			WorkArea terminology = new WorkArea();
			if (nodeterminology.Attributes["id"] != null)
				terminology.Id = nodeterminology.Attributes["id"].Value;
			if (nodeterminology.Attributes["name"] != null)
				terminology.Name = nodeterminology.Attributes["name"].Value;

			_project.WorkArea = terminology;

			//Extract Product
			XmlNodeList products = nodeProject.SelectNodes("//Product");
			if ((products == null) || (products.Count == 0) || (products.Count != 1))
			{
				//Send warning
			}

			XmlNode nodeproduct = products[0];

			Product product = new Product();
			if (nodeproduct.Attributes["id"] != null)
				product.Id = nodeproduct.Attributes["id"].Value;
			if (nodeproduct.Attributes["name"] != null)
				product.Name = nodeproduct.Attributes["name"].Value;

			_project.Product = product;


			//Extract Content
			XmlNodeList nodecontents = nodeProject.SelectNodes("//Content/ContentEntity");
			if (nodecontents != null)
			{
				IList<ContentEntity> contents = new List<ContentEntity>();

				foreach (XmlNode nodecontent in nodecontents)
				{
					ContentEntity ce = new ContentEntity();
					ParseExtendedInfo(nodecontent, ce);
					if (nodecontent.Attributes["id"] != null)
						ce.Id = nodecontent.Attributes["id"].Value;
					if (nodecontent.Attributes["name"] != null)
						ce.Name = nodecontent.Attributes["name"].Value;
					if (nodecontent.Attributes["version"] != null)
						ce.Version = nodecontent.Attributes["version"].Value;
					if (nodecontent.Attributes["type"] != null)
						ce.Type = nodecontent.Attributes["type"].Value;


					XmlNode nodebodys = nodeProject.SelectSingleNode("//Content/ContentEntity/Body");

					if (nodebodys != null)
					{
						XmlNode childNode = nodebodys.ChildNodes[0];
						if (childNode is XmlCDataSection)
						{
							XmlCDataSection cdataSection = childNode as XmlCDataSection;
							ce.Content = cdataSection.Value;
						}

					}

					ce.Project = _project;

					if (nodecontent.Attributes["language"] != null)
					{
						String languageId= nodecontent.Attributes["language"].Value;
						ce.Language = _project.FindLanguage(languageId);

						if(ce.Language == null)
						{
							ce.Language = new Language();
							ce.Language.LanguageId = languageId;
						}
					}
					contents.Add(ce);
				}

				_project.Contents = contents.ToArray();
			}

			//Extract Transltions
			XmlNodeList translationsnodes = nodeProject.SelectNodes("//Translations/Translation");
			if (translationsnodes != null)
			{
				IList<Translation> translations = new List<Translation>();

				foreach (XmlNode translationnode in translationsnodes)
				{
					Translation translation = new Translation();
					ParseExtendedInfo(translationnode, translation);
					if (translationnode.Attributes["id"] != null)
						translation.Id = translationnode.Attributes["id"].Value;
					if (translationnode.Attributes["progress"] != null)
						translation.Progress = int.Parse(translationnode.Attributes["progress"].Value);
					if (translationnode.Attributes["status"] != null)
						translation.Status = translationnode.Attributes["status"].Value;

					if (translationnode.Attributes["comment"] != null)
						translation.Comment = translationnode.Attributes["comment"].Value;


					contact = translationnode.SelectSingleNode("//Responsible");
					if (contact != null)
					{
						contactcontext.SetContext(contact);
						translation.Responsible = (Contact)contactcontext.GetContext();
					}


					LanguagePair pair = new LanguagePair();

					if (translationnode.Attributes["sourceLanguage"] != null)
					{
						String sourceLanguageId = translationnode.Attributes["sourceLanguage"].Value;
						pair.SourceLanguage = _project.FindLanguage(sourceLanguageId);

						if (pair.SourceLanguage == null)
						{
							pair.SourceLanguage = new Language();
							pair.SourceLanguage.LanguageId = sourceLanguageId;
						}
					}
					if (translationnode.Attributes["targetLanguage"] != null)
					{
						String targetLanguageId = translationnode.Attributes["targetLanguage"].Value;
						pair.TargetLanguage = _project.FindLanguage(targetLanguageId);

						if (pair.TargetLanguage == null)
						{
							pair.TargetLanguage = new Language();
							pair.TargetLanguage.LanguageId = targetLanguageId;
						}
					}

					translation.LanguagePair = pair;
					translation.Project = _project;

					if (translationnode.Attributes["sourceContentId"] != null)
					{
						string sourceconentId = translationnode.Attributes["sourceContentId"].Value;
						if (!String.IsNullOrEmpty(sourceconentId))
						{
							translation.SourceContent = _project.FindContent(sourceconentId);
						}
					}


					if (translationnode.Attributes["targetContentId"] != null)
					{
						string targetcontentId = translationnode.Attributes["targetContentId"].Value;

						if (!String.IsNullOrEmpty(targetcontentId))
						{
							translation.TargetContent = _project.FindContent(targetcontentId);
						}
					}
					translations.Add(translation);
				}
				_project.Translations = translations.ToArray();
			}
		}

		public override object GetContext()
		{
			return _project;
		}
	}
}